﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace LunarSF.SHomeWorkshop.LunarMarkdownEditor
{
    public class OptionQuestionProcesser
    {
        /// <summary>
        /// 将原型写成 LME 识别的选择题。
        /// </summary>
        /// <param name="src"></param>
        /// <returns></returns>
        public static string ConvertToExamText(string src)
        {
            var sBuilder = new StringBuilder();


            //选择题通常应类似这样：
            //1．下列对鲁国宗法等级关系的排列，正确的是(     )
            //A.天子―诸侯―士―卿大夫       B.天子―卿大夫―诸侯―士
            //C.诸侯―卿大夫―士             D.卿大夫―士―诸侯
            //【答案】C
            //【解析】
            //试题分析：本题考查学生根据所学知识解决问题的能力。根据所学可知西周实行分封制度，依据宗法制形成了天子——诸侯——卿大夫——士的等级关系。材料强调是鲁国宗法等级关系的排列，因此最高国君为诸侯，依次为诸侯―卿大夫―士。C符合题意。
            //考点：古代中国的政治制度·中国早期政治制度的特点·宗法制

            string[] lines = FormatChars(src).Split(new char[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);

            string previewQTitle = "";
            string qTitle = "";
            List<OptionQuestionBranch> branches = new List<OptionQuestionBranch>();
            List<OptionQuestionBranch> numBranches = new List<OptionQuestionBranch>();
            string answerMark = "";
            string analysisText = "";
            string examPointText = "";
            string pathOfImage = "";
            char[] trimChars = new char[] { ' ', '　', '\t' };

            int questionIndex = 1;
            bool anaIsOpen = false;

            foreach (var line in lines)
            {
                if (IsQTitle(line, ref previewQTitle, ref qTitle))
                {
                    //结束上一题的解析文本
                    anaIsOpen = false;

                    //先拼合上一道试题
                    if (string.IsNullOrWhiteSpace(previewQTitle) == false)
                    {

                        if (AppandQuestion(ref questionIndex, sBuilder, examPointText, ref pathOfImage, ref previewQTitle, ref qTitle,
                            branches, numBranches, answerMark, analysisText, trimChars) == false)
                        {
                            return "";
                        }
                    }
                    else
                    {
                        previewQTitle = qTitle;
                    }

                    //再清除旧的试题
                    branches.Clear();
                    numBranches.Clear();
                    answerMark = "";
                    analysisText = "";
                    examPointText = "";
                    continue;
                }

                if (IsBranch(line, ref branches)) continue;
                if (IsNumBranch(line, ref numBranches)) continue;
                if (IsAnswerLine(line, ref answerMark)) continue;

                if (IsExamPoint(line, ref examPointText)) continue;
                if (IsPathOfImage(line, ref pathOfImage)) continue;

                if (anaIsOpen)  //注意：解析总是在最后的。
                {
                    if (line.StartsWith("【") || line.StartsWith("["))
                    {
                        var indexOfCloseMark = line.IndexOf('】');
                        if (indexOfCloseMark >= 1)
                        {
                            var tailline = line.Substring(indexOfCloseMark + 1);
                            analysisText += tailline;
                            continue;
                        }
                        else
                        {
                            indexOfCloseMark = line.IndexOf(']');
                            var tailline = line.Substring(indexOfCloseMark + 1);
                            analysisText += tailline;
                            continue;
                        }
                    }
                    analysisText += line.Trim(trimChars);
                    continue;
                }
                else
                {
                    if (IsAnalysis(line, ref analysisText))
                    {
                        anaIsOpen = true;
                        continue;
                    }
                }

                //continue;
            }

            //添加最后一题。
            previewQTitle = qTitle;
            if (string.IsNullOrEmpty(previewQTitle) == false)
            {
                if (AppandQuestion(ref questionIndex, sBuilder, examPointText, ref pathOfImage, ref previewQTitle,
                     ref qTitle, branches, numBranches, answerMark, analysisText, trimChars) == false)
                {
                    return "";
                }
            }

            return sBuilder.ToString();
        }

        private static string FormatChars(string src)
        {
            return src
                .Replace('Ａ', 'A')
                .Replace('Ｂ', 'B')
                .Replace('Ｃ', 'C')
                .Replace('Ｄ', 'D')
                .Replace('Ｅ', 'E')
                .Replace('Ｆ', 'F')
                .Replace('Ｇ', 'G')
                .Replace('Ｈ', 'H')
                .Replace('Ｉ', 'I')
                .Replace('Ｊ', 'J')
                .Replace('Ｋ', 'K')
                .Replace('Ｌ', 'L')
                .Replace('Ｍ', 'M')
                .Replace('Ｎ', 'N')
                .Replace('Ｏ', 'O')
                .Replace('Ｐ', 'P')
                .Replace('Ｑ', 'Q')
                .Replace('Ｒ', 'R')
                .Replace('Ｓ', 'S')
                .Replace('Ｔ', 'T')
                .Replace('Ｕ', 'U')
                .Replace('Ｖ', 'V')
                .Replace('Ｗ', 'W')
                .Replace('Ｘ', 'X')
                .Replace('Ｙ', 'Y')
                .Replace('Ｚ', 'Z')
                .Replace('ａ', 'a')
                .Replace('ｂ', 'b')
                .Replace('ｃ', 'c')
                .Replace('ｄ', 'd')
                .Replace('ｅ', 'e')
                .Replace('ｆ', 'f')
                .Replace('ｇ', 'g')
                .Replace('ｈ', 'h')
                .Replace('ｉ', 'i')
                .Replace('ｊ', 'j')
                .Replace('ｋ', 'k')
                .Replace('ｌ', 'l')
                .Replace('ｍ', 'm')
                .Replace('ｎ', 'n')
                .Replace('ｏ', 'o')
                .Replace('ｐ', 'p')
                .Replace('ｑ', 'q')
                .Replace('ｒ', 'r')
                .Replace('ｓ', 's')
                .Replace('ｔ', 't')
                .Replace('ｕ', 'u')
                .Replace('ｖ', 'v')
                .Replace('ｗ', 'w')
                .Replace('ｘ', 'x')
                .Replace('ｙ', 'y')
                .Replace('ｚ', 'z')
                .Replace('１', '1')
                .Replace('２', '2')
                .Replace('３', '3')
                .Replace('４', '4')
                .Replace('５', '5')
                .Replace('６', '6')
                .Replace('７', '7')
                .Replace('８', '8')
                .Replace('９', '9')
                .Replace('０', '0');
        }

        private static bool AppandQuestion(ref int questionIndex, StringBuilder sBuilder,
            string examPointText, ref string pathOfImage, ref string previewQTitle,
            ref string qTitle,
            List<OptionQuestionBranch> branches,
            List<OptionQuestionBranch> numBranches,
            string answerMark,
            string analysisText,
            char[] trimChars)
        {
            if (string.IsNullOrWhiteSpace(previewQTitle))
            {
                LMessageBox.Show("未找到题干文本！", Globals.AppName, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Warning);
                return false;
            }

            if (branches == null || branches.Count <= 1)
            {
                LMessageBox.Show("题支数量不足！", Globals.AppName, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Warning);
                return false;
            }

            if (string.IsNullOrWhiteSpace(answerMark))
            {
                LMessageBox.Show("没找到答案文本！", Globals.AppName, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Warning);
                return false;
            }

            answerMark = answerMark.ToLower();

            OptionQuestionBranch answerBranch = null;
            var answerCount = 0;
            foreach (var branch in branches)
            {
                if (branch.Mark.ToLower().StartsWith(answerMark))
                {
                    branch.IsAnswerBranch = true;
                    branch.IsErrorBranch = false;
                    answerBranch = branch;
                    answerCount++;
                }
                else
                {
                    branch.IsAnswerBranch = false;
                    branch.IsErrorBranch = true;
                }
            }

            if (answerCount < 1)
            {
                LMessageBox.Show("没找到答案选项，必须提供一个答案选项。", Globals.AppName, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Warning);
                return false;
            }

            if (answerCount > 1)
            {
                LMessageBox.Show("答案选项数目不对。只支持单项选择题！", Globals.AppName, System.Windows.MessageBoxButton.OK, System.Windows.MessageBoxImage.Warning);
                return false;
            }

            var numBranchesText = "";

            StringBuilder sb = new StringBuilder();
            if (numBranches.Count > 0)
            {
                sb.Append("：");
                foreach (var item in numBranches)
                {
                    sb.Append(item.Mark.Trim(trimChars));
                    sb.Append(item.Text.Trim(trimChars));
                    sb.Append("　");
                }
                numBranchesText = sb.ToString();
                numBranchesText = numBranchesText.Trim(trimChars);
            }

            //第 {questionIndex++} 题　//这个还是不加比较好，烦人。
            if (string.IsNullOrWhiteSpace(examPointText) == false)
            {
                sBuilder.Append($"\r\n；[第 {questionIndex++} 题]考点：" + examPointText + "\r\n\r\n");
            }

            sBuilder.Append("　　试题＞＞(." + (questionIndex++) + ".)" + previewQTitle.Trim(trimChars) + numBranchesText + $"【{answerBranch.Text}】\r\n\r\n");

            if (string.IsNullOrWhiteSpace(pathOfImage) == false)
            {
                sBuilder.Append("\r\n" + pathOfImage + "\r\n");
                pathOfImage = "";
            }

            sBuilder.Append("　　答案＞＞" + answerBranch.Text + "\r\n");

            if (string.IsNullOrWhiteSpace(analysisText) == false)
            {
                sBuilder.Append("　　解析＞＞" +
                    // 格式化选择题解析文本。
                    analysisText
                        .Replace("A", "此")
                        .Replace("B", "此")
                        .Replace("C", "此")
                        .Replace("D", "此")
                        .Replace("此选项", "此项")
                        .Replace("为此此项", "此项")
                        .Replace("故此此项", "此项")
                        .Replace("此此项", "此项")
                        .Replace("此、此、此项", "另三项") + "\r\n\r\n");
            }
            else
            {
                sBuilder.Append("　　解析＞＞\r\n\r\n");
            }

            foreach (var branch in branches)
            {
                if (branch.IsAnswerBranch) continue;
                sBuilder.Append("　　错项＞＞" + branch.Text + "\r\n");
                sBuilder.Append("　　解析＞＞" + "\r\n\r\n");
            }
            sBuilder.Append("〓〓〓〓〓〓\r\n\r\n");

            return true;
        }

        public static bool IsQTitle(string line, ref string previewQTitle, ref string qtitle)
        {
            Regex reg = new Regex(@"(?<=(^[0123456789０１２３４５６７８９]{1,}[.．、])).*(?=(([\(（【][ 　\t]{0,}[）\)】]){0,}))");
            var match = reg.Match(line);

            if (match.Success)
            {
                previewQTitle = qtitle;

                var regEndBrackets = new Regex(@"[\(（【][\?  　\t]{0,}[）\)】]$", RegexOptions.RightToLeft);
                var matchEndBrackets = regEndBrackets.Match(match.Value);
                if (matchEndBrackets.Success)
                {
                    qtitle = match.Value.Substring(0, matchEndBrackets.Index);
                }
                else qtitle = match.Value;
                return true;
            }

            //没有以数字开头，看末尾有没有一对括号及若干空格结尾。
            Regex regEnd = new Regex(@"([\(（【][ 　\t]{0,}[）\)】]){1,}", RegexOptions.RightToLeft);
            var matchEnd = regEnd.Match(line);
            if (matchEnd.Success)
            {
                qtitle = line.Substring(0, matchEnd.Index).Trim(new char[] { ' ', '　', '\t' });

                return string.IsNullOrWhiteSpace(qtitle) == false;
            }

            return false;
        }

        public static bool IsNumBranch(string line, ref List<OptionQuestionBranch> numBranches)
        {
            var regStartNumBranch = new Regex(@"^[ 　\t]{0,}[①②③④⑤⑥⑦⑧⑨⑩][ 　\t]{0,}");
            if (regStartNumBranch.Match(line).Success == false) return false;

            var regNumBranch = new Regex(@"[①②③④⑤⑥⑦⑧⑨⑩][ 　\t]{0,}");
            MatchCollection matches = regNumBranch.Matches(line);
            int count = 0;
            for (int i = matches.Count - 1; i >= 0; i--)
            {
                Match match = matches[i];
                string mark = match.Value, text;
                text = line.Substring(match.Index + match.Length);
                line = line.Substring(0, match.Index);

                numBranches.Add(new LunarMarkdownEditor.OptionQuestionBranch()
                {
                    Mark = mark,
                    Text = text.Trim(new char[] { ' ', '　', '\t' }),
                });
                count++;
            }
            numBranches.Sort(new QuestionBranchCompare());
            return count > 0;
        }

        /// <summary>
        /// 判断是否选择支文本行，有时候一个文本行里包括多个选择支。
        /// </summary>
        public static bool IsBranch(string line, ref List<OptionQuestionBranch> branches)
        {
            var regStartBranch = new Regex(@"^[ 　\t]{0,}[ABCDＡＢＣＤ][ 　\t]{0,}[.．。,，、]");
            if (regStartBranch.Match(line).Success == false) return false;

            var regBranch = new Regex(@"[ABCDＡＢＣＤ][ 　\t]{0,}[.．。,，、]");
            MatchCollection matches = regBranch.Matches(line);
            int count = 0;
            for (int i = matches.Count - 1; i >= 0; i--)
            {
                Match match = matches[i];
                string mark = match.Value, text;
                text = line.Substring(match.Index + match.Length);
                line = line.Substring(0, match.Index);

                branches.Add(new LunarMarkdownEditor.OptionQuestionBranch()
                {
                    Mark = mark.Trim(new char[] { '.', '．', '、', ' ', ' ', '　', '\t' }),
                    Text = text.Trim(new char[] { ' ', '　', '\t' }),
                });
                count++;
            }
            branches.Sort(new QuestionBranchCompare());
            return count > 0;
        }

        /// <summary>
        /// 判断文本行是否试题分析行。
        /// </summary>
        public static bool IsAnalysis(string line, ref string analysisText)
        {
            var trimChars = new char[] { ' ', '　', '\t' };
            if (string.IsNullOrWhiteSpace(line)) return false;
            if (line.StartsWith("试题分析："))
            {
                analysisText += line.Substring(5).Trim(new char[] { ' ', '　', '\t' });
                return true;
            }
            else
            {
                var regAna = new Regex(@"[【\[](详解|解析)[】\]]");
                var matchAna = regAna.Match(line);
                if (matchAna.Success)
                {
                    var text = line.Substring(4).Trim(trimChars);
                    if (string.IsNullOrWhiteSpace(text) == false)
                    {
                        analysisText += text.Trim(trimChars);
                    }

                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// 判断当前行是否试题答案行。
        /// </summary>
        public static bool IsAnswerLine(string line, ref string answerMark)
        {
            if (string.IsNullOrWhiteSpace(line))
            {
                return false;
            }

            Regex reg = new Regex(@"(?<=(^[ 　\t]{0,}(([【\[]答案[】\]])|(答案[:：]))[ 　\t]{0,})).*");
            var match = reg.Match(line);
            if (match.Success)
            {
                answerMark = match.Value.Trim(new char[] { ' ', '　', '\t' }).ToLower();
                return true;
            }

            return false;
        }

        /// <summary>
        /// 是否考点说明行。
        /// </summary>
        public static bool IsExamPoint(string line, ref string examPointText)
        {
            if (string.IsNullOrWhiteSpace(line)) return false;
            if (line.StartsWith("考点："))
            {
                examPointText = line.Substring(3);
                return true;
            }

            if (line.StartsWith("【考点】"))
            {
                examPointText = line.Substring(4);
                return true;
            }

            return false;
        }

        public static bool IsPathOfImage(string line, ref string pathOfImage)
        {
            if (CustomMarkdownSupport.IsImageLinkLine(line))
            {
                pathOfImage = line;
                return true;
            }
            else
            {
                pathOfImage = "";  // 这行不能注释掉，否则从此开始每一题都会有图了
                return false;
            }
        }

        /// <summary>
        /// 判断指定文本行是否没什么用处的无意义行。
        /// </summary>
        public static bool IsNoUsefulLine(string line)
        {
            if (string.IsNullOrWhiteSpace(line)) return true;
            Regex reg = new Regex(@"^[ 　\t]{0,}【解析】[ 　\t]{0,}$");
            if (reg.Match(line).Success) return true;

            return true;
        }
    }

    /// <summary>
    /// 表示一个选择支。
    /// </summary>
    public class OptionQuestionBranch
    {
        /// <summary>
        /// 只应是“ABCD”四个字母之一。
        /// </summary>
        public string Mark { get; set; }

        /// <summary>
        /// 选择支的文本，不包括用作选项标记的ABCD字样。
        /// </summary>
        public string Text { get; set; }

        /// <summary>
        /// 是否答案。
        /// </summary>
        public bool IsAnswerBranch { get; set; } = false;

        /// <summary>
        /// 是否错项。
        /// </summary>
        public bool IsErrorBranch { get; set; } = true;
    }

    public class QuestionBranchCompare : IComparer<OptionQuestionBranch>
    {
        public int Compare(OptionQuestionBranch x, OptionQuestionBranch y)
        {
            return x.Mark.ToLower().CompareTo(y.Mark.ToLower());
        }
    }
}
